'use client'

import { useState, useEffect } from 'react'
import {
  DocumentTextIcon,
  TrashIcon,
  MagnifyingGlassIcon,
  FunnelIcon,
  ArrowDownTrayIcon,
  PlayIcon,
  MusicalNoteIcon,
  PhotoIcon,
  CheckCircleIcon,
  XCircleIcon,
  ClockIcon,
  SpeakerWaveIcon
} from '@heroicons/react/24/outline'
import VideoDetailModal from '@/components/VideoDetailModal'
import TextRewriteModal from '@/components/TextRewriteModal'
import Pagination from '@/components/Pagination'

// Toast通知组件
function Toast({ message, type, onClose }: { message: string, type: 'success' | 'error' | 'info', onClose: () => void }) {
  const bgColor = type === 'success' ? 'bg-green-500' : type === 'error' ? 'bg-red-500' : 'bg-blue-500'

  return (
    <div className={`fixed top-4 right-4 ${bgColor} text-white px-6 py-3 rounded-lg shadow-lg z-50 flex items-center space-x-2`}>
      <span>{message}</span>
      <button onClick={onClose} className="text-white hover:text-gray-200">
        ✕
      </button>
    </div>
  )
}

interface Video {
  id: number
  videoId: string
  url: string
  title: string | null
  description: string | null
  author: string | null
  authorId: string | null
  authorFollowers: number | null
  authorFollowing: number | null
  likes: number | null
  shares: number | null
  comments: number | null
  views: number | null
  duration: number | null
  videoUrl: string | null
  audioUrl: string | null
  coverUrl: string | null
  hashtags: string | null
  musicTitle: string | null
  musicAuthor: string | null
  publishTime: string | null
  localVideoPath: string | null
  localAudioPath: string | null
  localCoverPath: string | null
  downloadStatus: string | null
  downloadProgress: number | null
  fileSize: number | null
  createdAt: string
  textExtractions: {
    id: number
    status: string
    method: string
    extractedText: string
    confidence?: number
    language?: string
    createdAt: string
  }[]
  rewrittenTexts: {
    id: number
    originalText: string
    rewrittenText: string
    style: string
    tone: string
    length: string
    requirements?: string
    createdAt: string
  }[]
}

interface Filters {
  search: string
  author: string
  hasText: string
  dateRange: string
}

export default function ContentManagePage() {
  const [videos, setVideos] = useState<Video[]>([])
  const [loading, setLoading] = useState(true)
  const [filters, setFilters] = useState<Filters>({
    search: '',
    author: '',
    hasText: '',
    dateRange: ''
  })
  const [selectedVideos, setSelectedVideos] = useState<number[]>([])
  const [showFilters, setShowFilters] = useState(false)
  const [selectedVideo, setSelectedVideo] = useState<Video | null>(null)
  const [isDetailModalOpen, setIsDetailModalOpen] = useState(false)
  const [processingVideos, setProcessingVideos] = useState<Set<number>>(new Set())
  const [toast, setToast] = useState<{message: string, type: 'success' | 'error' | 'info'} | null>(null)
  const [isRewriteModalOpen, setIsRewriteModalOpen] = useState(false)
  const [pagination, setPagination] = useState({
    page: 1,
    limit: 20,
    total: 0,
    pages: 0
  })

  useEffect(() => {
    fetchVideos()
  }, [pagination.page, filters])

  // Toast通知函数
  const showToast = (message: string, type: 'success' | 'error' | 'info' = 'info') => {
    setToast({ message, type })
    setTimeout(() => setToast(null), 3000) // 3秒后自动消失
  }

  // 批量改写文案
  const handleBatchRewrite = async (options: {prompt: string}) => {
    if (selectedVideos.length === 0) {
      showToast('请先选择要改写的视频', 'error')
      return
    }

    if (!options.prompt.trim()) {
      showToast('请输入改写提示词', 'error')
      return
    }

    try {
      showToast(`正在改写 ${selectedVideos.length} 个视频的文案...`, 'info')

      const response = await fetch('/api/content/rewrite', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          videoIds: selectedVideos,
          prompt: options.prompt
        }),
      })

      const data = await response.json()

      if (data.success) {
        if (data.taskStarted) {
          // 后台任务已启动
          showToast(`${data.message}，请稍后刷新页面查看结果`, 'info')
          setSelectedVideos([]) // 清空选择
          setIsRewriteModalOpen(false) // 关闭模态框

          // 10秒后自动刷新一次
          setTimeout(() => {
            fetchVideos()
            showToast('页面已自动刷新，请查看改写结果', 'info')
          }, 10000)
        } else {
          showToast(data.message, 'success')
          setSelectedVideos([]) // 清空选择
          setIsRewriteModalOpen(false) // 关闭模态框
          fetchVideos() // 刷新列表
        }
      } else {
        showToast(data.error || '改写失败', 'error')
      }
    } catch (error) {
      showToast('网络错误，请重试', 'error')
    }
  }

  const fetchVideos = async () => {
    setLoading(true)
    try {
      const params = new URLSearchParams({
        page: pagination.page.toString(),
        limit: pagination.limit.toString(),
        ...(filters.search && { search: filters.search }),
        ...(filters.author && { author: filters.author }),
        ...(filters.hasText && { hasText: filters.hasText }),
        ...(filters.dateRange && { dateRange: filters.dateRange })
      })

      const response = await fetch(`/api/content/videos?${params}`)
      if (response.ok) {
        const data = await response.json()
        setVideos(data.videos)
        setPagination(prev => ({
          ...prev,
          total: data.pagination.total,
          pages: data.pagination.pages
        }))
      }
    } catch (error) {
      console.error('Failed to fetch videos:', error)
    } finally {
      setLoading(false)
    }
  }

  const handleExtractText = async (videoId: number) => {
    // 添加到处理中状态
    setProcessingVideos(prev => new Set([...prev, videoId]))

    try {
      // 获取视频信息以确定是否有音频
      const video = videos.find(v => v.id === videoId)

      if (!video) {
        showToast('视频不存在', 'error')
        return
      }

      // 如果有音频URL，优先使用语音识别
      if (video.audioUrl) {
        showToast('正在进行语音识别，请稍候...', 'info')

        const response = await fetch('/api/content/transcribe', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            videoId,
            languageHints: ['auto'], // 自动检测语言
            disfluencyRemovalEnabled: true // 过滤语气词
          }),
        })

        const data = await response.json()

        if (data.success) {
          showToast('语音识别文案提取完成！', 'success')
          fetchVideos() // 刷新列表以显示识别结果
        } else {
          showToast(data.error || '语音识别失败，请重试', 'error')
        }
      } else {
        // 如果没有音频URL，回退到OCR方式
        showToast('正在进行OCR文案提取，请稍候...', 'info')

        const response = await fetch('/api/tiktok/extract-text', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({ videoId, method: 'OCR' }),
        })

        if (response.ok) {
          showToast('OCR文案提取已开始', 'success')
          fetchVideos()
        } else {
          const data = await response.json()
          showToast(data.error || '提取失败', 'error')
        }
      }
    } catch (error) {
      showToast('网络错误，请重试', 'error')
    } finally {
      // 从处理中状态移除
      setProcessingVideos(prev => {
        const newSet = new Set(prev)
        newSet.delete(videoId)
        return newSet
      })
    }
  }

  const handleDeleteVideo = async (videoId: number) => {
    if (!confirm('确定要删除这个视频吗？')) return

    try {
      const response = await fetch(`/api/content/videos/${videoId}`, {
        method: 'DELETE'
      })

      if (response.ok) {
        showToast('删除成功', 'success')
        fetchVideos()
      } else {
        showToast('删除失败', 'error')
      }
    } catch (error) {
      showToast('网络错误，请重试', 'error')
    }
  }

  const handleDownloadFiles = async (videoId: number) => {
    setProcessingVideos(prev => new Set([...prev, videoId]))
    showToast('正在下载文件到本地，请稍候...', 'info')

    try {
      const response = await fetch('/api/content/download', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ videoId }),
      })

      const data = await response.json()

      if (data.success) {
        showToast('文件下载完成', 'success')
        fetchVideos() // 刷新列表以显示下载状态
      } else {
        showToast(data.error || '下载失败', 'error')
      }
    } catch (error) {
      showToast('网络错误，请重试', 'error')
    } finally {
      setProcessingVideos(prev => {
        const newSet = new Set(prev)
        newSet.delete(videoId)
        return newSet
      })
    }
  }

  const handleBatchDownload = async () => {
    const selectedIds = videos
      .filter((_, index) => selectedVideos.includes(index))
      .map(video => video.id)

    if (selectedIds.length === 0) {
      alert('请选择要下载的视频')
      return
    }

    try {
      const response = await fetch('/api/content/download', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ videoIds: selectedIds }),
      })

      const data = await response.json()

      if (data.success) {
        alert(data.message)
        fetchVideos() // 刷新列表
        setSelectedVideos([]) // 清空选择
      } else {
        alert(data.error || '批量下载失败')
      }
    } catch (error) {
      alert('网络错误，请重试')
    }
  }

  const handleViewVideo = (video: Video) => {
    setSelectedVideo(video)
    setIsDetailModalOpen(true)
  }

  const handleCloseDetailModal = () => {
    setIsDetailModalOpen(false)
    setSelectedVideo(null)
  }

  const handleTranscribeAudio = async (videoId: number) => {
    setProcessingVideos(prev => new Set([...prev, videoId]))
    showToast('正在进行语音识别，请稍候...', 'info')

    try {
      const response = await fetch('/api/content/transcribe', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          videoId,
          languageHints: ['auto'], // 自动检测语言
          disfluencyRemovalEnabled: true // 过滤语气词
        }),
      })

      const data = await response.json()

      if (data.success) {
        showToast('语音识别完成！', 'success')
        fetchVideos() // 刷新列表以显示识别结果
      } else {
        showToast(data.error || '语音识别失败', 'error')
      }
    } catch (error) {
      showToast('网络错误，请重试', 'error')
    } finally {
      setProcessingVideos(prev => {
        const newSet = new Set(prev)
        newSet.delete(videoId)
        return newSet
      })
    }
  }

  const handleBatchTranscribe = async () => {
    const selectedIds = videos
      .filter((_, index) => selectedVideos.includes(index))
      .map(video => video.id)

    if (selectedIds.length === 0) {
      alert('请选择要进行语音识别的视频')
      return
    }

    try {
      const response = await fetch('/api/content/transcribe', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          videoIds: selectedIds,
          languageHints: ['auto'],
          disfluencyRemovalEnabled: true
        }),
      })

      const data = await response.json()

      if (data.success) {
        alert(data.message)
        fetchVideos() // 刷新列表
        setSelectedVideos([]) // 清空选择
      } else {
        alert(data.error || '批量语音识别失败')
      }
    } catch (error) {
      alert('网络错误，请重试')
    }
  }

  const handleBatchExtractText = async () => {
    const selectedVideoData = videos.filter((_, index) => selectedVideos.includes(index))

    if (selectedVideoData.length === 0) {
      alert('请选择要提取文案的视频')
      return
    }

    try {
      // 分离有音频和无音频的视频
      const videosWithAudio = selectedVideoData.filter(video => video.audioUrl)
      const videosWithoutAudio = selectedVideoData.filter(video => !video.audioUrl)

      let results = []

      // 对有音频的视频使用语音识别
      if (videosWithAudio.length > 0) {
        const audioVideoIds = videosWithAudio.map(video => video.id)
        const response = await fetch('/api/content/transcribe', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            videoIds: audioVideoIds,
            languageHints: ['auto'],
            disfluencyRemovalEnabled: true
          }),
        })

        const data = await response.json()
        if (data.success) {
          results.push(`语音识别: ${data.summary.success} 成功, ${data.summary.failed} 失败`)
        }
      }

      // 对无音频的视频使用OCR
      if (videosWithoutAudio.length > 0) {
        for (const video of videosWithoutAudio) {
          try {
            const response = await fetch('/api/tiktok/extract-text', {
              method: 'POST',
              headers: {
                'Content-Type': 'application/json',
              },
              body: JSON.stringify({ videoId: video.id, method: 'OCR' }),
            })

            if (response.ok) {
              results.push(`OCR提取: 视频 ${video.id} 已开始处理`)
            }
          } catch (error) {
            console.error(`OCR extraction failed for video ${video.id}:`, error)
          }
        }
      }

      if (results.length > 0) {
        alert(`批量文案提取完成:\n${results.join('\n')}`)
        fetchVideos() // 刷新列表
        setSelectedVideos([]) // 清空选择
      } else {
        alert('批量文案提取失败')
      }
    } catch (error) {
      alert('网络错误，请重试')
    }
  }

  const handleBatchDelete = async () => {
    if (selectedVideos.length === 0) {
      alert('请选择要删除的视频')
      return
    }

    if (!confirm(`确定要删除选中的 ${selectedVideos.length} 个视频吗？`)) return

    try {
      const response = await fetch('/api/content/videos/batch', {
        method: 'DELETE',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ videoIds: selectedVideos }),
      })

      if (response.ok) {
        alert('批量删除成功')
        setSelectedVideos([])
        fetchVideos()
      } else {
        alert('批量删除失败')
      }
    } catch (error) {
      alert('网络错误，请重试')
    }
  }

  const handleExport = async () => {
    try {
      const params = new URLSearchParams({
        ...(filters.search && { search: filters.search }),
        ...(filters.author && { author: filters.author }),
        ...(filters.hasText && { hasText: filters.hasText }),
        ...(filters.dateRange && { dateRange: filters.dateRange })
      })

      const response = await fetch(`/api/content/export?${params}`)
      if (response.ok) {
        const blob = await response.blob()
        const url = window.URL.createObjectURL(blob)
        const a = document.createElement('a')
        a.href = url
        a.download = `tiktok_content_${new Date().toISOString().split('T')[0]}.csv`
        document.body.appendChild(a)
        a.click()
        window.URL.revokeObjectURL(url)
        document.body.removeChild(a)
      } else {
        alert('导出失败')
      }
    } catch (error) {
      alert('导出失败')
    }
  }

  const toggleVideoSelection = (videoId: number) => {
    setSelectedVideos(prev => 
      prev.includes(videoId) 
        ? prev.filter(id => id !== videoId)
        : [...prev, videoId]
    )
  }

  const toggleAllSelection = () => {
    if (selectedVideos.length === videos.length) {
      setSelectedVideos([])
    } else {
      setSelectedVideos(videos.map(v => v.id))
    }
  }

  if (loading) {
    return (
      <div className="flex items-center justify-center h-64">
        <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-indigo-600"></div>
      </div>
    )
  }

  return (
    <div>
      <div className="sm:flex sm:items-center sm:justify-between">
        <div className="sm:flex-auto">
          <h1 className="text-xl font-semibold text-gray-900">内容管理</h1>
          <p className="mt-2 text-sm text-gray-700">
            管理从TikTok采集的视频内容和提取的文案
          </p>
        </div>
        <div className="mt-4 sm:mt-0 sm:ml-16 sm:flex-none flex space-x-3">
          <button
            onClick={() => setShowFilters(!showFilters)}
            className="inline-flex items-center px-3 py-2 border border-gray-300 shadow-sm text-sm leading-4 font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
          >
            <FunnelIcon className="-ml-0.5 mr-2 h-4 w-4" />
            筛选
          </button>
          <button
            onClick={handleExport}
            className="inline-flex items-center px-3 py-2 border border-gray-300 shadow-sm text-sm leading-4 font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
          >
            <ArrowDownTrayIcon className="-ml-0.5 mr-2 h-4 w-4" />
            导出
          </button>
          {selectedVideos.length > 0 && (
            <>
              <button
                onClick={handleBatchDownload}
                className="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
              >
                <ArrowDownTrayIcon className="-ml-0.5 mr-2 h-4 w-4" />
                下载选中 ({selectedVideos.length})
              </button>
              <button
                onClick={handleBatchExtractText}
                className="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-white bg-green-600 hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500"
              >
                <DocumentTextIcon className="-ml-0.5 mr-2 h-4 w-4" />
                提取文案 ({selectedVideos.length})
              </button>
              <button
                onClick={handleBatchTranscribe}
                className="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-white bg-purple-600 hover:bg-purple-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-purple-500"
              >
                <SpeakerWaveIcon className="-ml-0.5 mr-2 h-4 w-4" />
                语音识别 ({selectedVideos.length})
              </button>
              <button
                onClick={() => setIsRewriteModalOpen(true)}
                className="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-white bg-orange-600 hover:bg-orange-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-orange-500"
              >
                <DocumentTextIcon className="-ml-0.5 mr-2 h-4 w-4" />
                改写文案 ({selectedVideos.length})
              </button>
              <button
                onClick={handleBatchDelete}
                className="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-white bg-red-600 hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500"
              >
                <TrashIcon className="-ml-0.5 mr-2 h-4 w-4" />
                删除选中 ({selectedVideos.length})
              </button>
            </>
          )}
        </div>
      </div>

      {/* 筛选器 */}
      {showFilters && (
        <div className="mt-6 bg-white shadow sm:rounded-lg p-6">
          <div className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4">
            <div>
              <label className="block text-sm font-medium text-gray-700">搜索</label>
              <div className="mt-1 relative">
                <input
                  type="text"
                  value={filters.search}
                  onChange={(e) => setFilters(prev => ({ ...prev, search: e.target.value }))}
                  className="block w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md leading-5 bg-white placeholder-gray-500 focus:outline-none focus:placeholder-gray-400 focus:ring-1 focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
                  placeholder="搜索标题、描述..."
                />
                <div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
                  <MagnifyingGlassIcon className="h-5 w-5 text-gray-400" />
                </div>
              </div>
            </div>
            <div>
              <label className="block text-sm font-medium text-gray-700">作者</label>
              <input
                type="text"
                value={filters.author}
                onChange={(e) => setFilters(prev => ({ ...prev, author: e.target.value }))}
                className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
                placeholder="作者用户名"
              />
            </div>
            <div>
              <label className="block text-sm font-medium text-gray-700">文案状态</label>
              <select
                value={filters.hasText}
                onChange={(e) => setFilters(prev => ({ ...prev, hasText: e.target.value }))}
                className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
              >
                <option value="">全部</option>
                <option value="yes">已提取</option>
                <option value="no">未提取</option>
              </select>
            </div>
            <div>
              <label className="block text-sm font-medium text-gray-700">时间范围</label>
              <select
                value={filters.dateRange}
                onChange={(e) => setFilters(prev => ({ ...prev, dateRange: e.target.value }))}
                className="mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
              >
                <option value="">全部时间</option>
                <option value="today">今天</option>
                <option value="week">本周</option>
                <option value="month">本月</option>
              </select>
            </div>
          </div>
        </div>
      )}

      {/* 视频列表 */}
      <div className="mt-8 flex flex-col">
        <div className="overflow-x-auto">
          <div className="inline-block min-w-full align-middle">
            <div className="overflow-hidden shadow ring-1 ring-black ring-opacity-5 md:rounded-lg relative">
              <table className="w-full divide-y divide-gray-300 table-fixed">
                <thead className="bg-gray-50">
                  <tr>
                    <th className="w-12 px-4 py-3 text-left">
                      <input
                        type="checkbox"
                        checked={selectedVideos.length === videos.length && videos.length > 0}
                        onChange={toggleAllSelection}
                        className="h-4 w-4 text-indigo-600 focus:ring-indigo-500 border-gray-300 rounded"
                      />
                    </th>
                    <th className="w-1/4 px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wide">
                      视频信息
                    </th>
                    <th className="w-24 px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wide">
                      作者信息
                    </th>
                    <th className="w-20 px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wide">
                      互动数据
                    </th>
                    <th className="w-16 px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wide">
                      媒体文件
                    </th>
                    <th className="w-20 px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wide">
                      下载状态
                    </th>
                    <th className="w-1/3 px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wide">
                      提取的文案
                    </th>
                    <th className="w-20 px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wide">
                      采集时间
                    </th>
                    <th className="w-32 px-4 py-3 sticky-actions bg-gray-50">
                      <span className="text-xs font-medium text-gray-500 uppercase tracking-wide">操作</span>
                    </th>
                  </tr>
                </thead>
                <tbody className="bg-white divide-y divide-gray-200">
                  {videos.map((video) => (
                    <tr key={video.id} className={selectedVideos.includes(video.id) ? 'bg-gray-50' : ''}>
                      <td className="px-4 py-4 whitespace-nowrap">
                        <input
                          type="checkbox"
                          checked={selectedVideos.includes(video.id)}
                          onChange={() => toggleVideoSelection(video.id)}
                          className="h-4 w-4 text-indigo-600 focus:ring-indigo-500 border-gray-300 rounded"
                        />
                      </td>
                      <td className="px-4 py-4">
                        <div className="flex items-center">
                          {video.coverUrl && (
                            <img
                              src={video.localCoverPath ? `/api/files/covers/${video.videoId}_cover.jpg` : video.coverUrl}
                              alt="封面"
                              className="h-12 w-12 rounded-lg object-cover mr-3"
                              onError={(e) => {
                                const target = e.target as HTMLImageElement;
                                target.style.display = 'none';
                              }}
                            />
                          )}
                          <div className="flex-1">
                            <div className="text-sm font-medium text-gray-900 line-clamp-2">
                              {video.title || `视频 ${video.videoId}`}
                            </div>
                            <div className="text-sm text-gray-500 line-clamp-3 mt-1">
                              {video.description}
                            </div>
                            {video.hashtags && (
                              <div className="mt-1 flex flex-wrap gap-1">
                                {JSON.parse(video.hashtags).slice(0, 2).map((tag: any, index: number) => (
                                  <span
                                    key={index}
                                    className="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-blue-100 text-blue-800"
                                  >
                                    #{tag.name || tag}
                                  </span>
                                ))}
                              </div>
                            )}
                            {video.musicTitle && (
                              <div className="text-xs text-gray-400 mt-1">
                                🎵 {video.musicTitle} - {video.musicAuthor}
                              </div>
                            )}
                          </div>
                        </div>
                      </td>
                      <td className="px-4 py-4 whitespace-nowrap text-sm text-gray-900">
                        <div>
                          <div className="font-medium">{video.author || '-'}</div>
                          {video.authorFollowers && (
                            <div className="text-xs text-gray-500">
                              粉丝: {video.authorFollowers.toLocaleString()}
                            </div>
                          )}
                        </div>
                      </td>
                      <td className="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
                        <div className="space-y-1 text-xs">
                          <div>👍 {video.likes?.toLocaleString() || 0}</div>
                          <div>👁️ {video.views?.toLocaleString() || 0}</div>
                          <div>💬 {video.comments?.toLocaleString() || 0}</div>
                          <div>📤 {video.shares?.toLocaleString() || 0}</div>
                          {video.duration && (
                            <div>⏱️ {Math.floor(video.duration / 60)}:{(video.duration % 60).toString().padStart(2, '0')}</div>
                          )}
                        </div>
                      </td>
                      <td className="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
                        <div className="space-y-1">
                          {video.videoUrl && (
                            <div className="flex items-center">
                              <PlayIcon className="h-3 w-3 mr-1" />
                              <span className="text-xs">视频</span>
                              {video.localVideoPath && (
                                <CheckCircleIcon className="h-3 w-3 ml-1 text-green-500" />
                              )}
                            </div>
                          )}
                          {video.audioUrl && (
                            <div className="flex items-center">
                              <MusicalNoteIcon className="h-3 w-3 mr-1" />
                              <span className="text-xs">音频</span>
                              {video.localAudioPath && (
                                <CheckCircleIcon className="h-3 w-3 ml-1 text-green-500" />
                              )}
                            </div>
                          )}
                          {video.coverUrl && (
                            <div className="flex items-center">
                              <PhotoIcon className="h-3 w-3 mr-1" />
                              <span className="text-xs">封面</span>
                              {video.localCoverPath && (
                                <CheckCircleIcon className="h-3 w-3 ml-1 text-green-500" />
                              )}
                            </div>
                          )}
                        </div>
                      </td>
                      <td className="px-4 py-4 whitespace-nowrap">
                        <div className="space-y-1">
                          {video.downloadStatus === 'completed' && (
                            <span className="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">
                              <CheckCircleIcon className="h-3 w-3 mr-1" />
                              已下载
                            </span>
                          )}
                          {video.downloadStatus === 'downloading' && (
                            <span className="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
                              <ClockIcon className="h-3 w-3 mr-1" />
                              下载中 {video.downloadProgress}%
                            </span>
                          )}
                          {video.downloadStatus === 'failed' && (
                            <span className="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800">
                              <XCircleIcon className="h-3 w-3 mr-1" />
                              下载失败
                            </span>
                          )}
                          {(!video.downloadStatus || video.downloadStatus === 'pending') && (
                            <span className="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800">
                              <ClockIcon className="h-3 w-3 mr-1" />
                              待下载
                            </span>
                          )}
                          {video.fileSize && (
                            <div className="text-xs text-gray-400">
                              {(video.fileSize / 1024 / 1024).toFixed(1)} MB
                            </div>
                          )}
                        </div>
                      </td>
                      <td className="px-4 py-4">
                        <div className="space-y-3">
                          {/* 原始文案 */}
                          {video.textExtractions.length > 0 ? (
                            <div className="space-y-2">
                              <div className="text-xs font-medium text-gray-600 mb-1">📝 原始文案</div>
                              {video.textExtractions.map((extraction, index) => (
                                <div key={index} className="border border-gray-200 rounded-lg p-3 bg-gray-50">
                                  <div className="flex items-center justify-between mb-2">
                                    <span className={`inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium ${
                                      extraction.status === 'completed' ? 'bg-green-100 text-green-800' :
                                      extraction.status === 'pending' ? 'bg-yellow-100 text-yellow-800' :
                                      'bg-red-100 text-red-800'
                                    }`}>
                                      {extraction.method} - {
                                        extraction.status === 'completed' ? '已完成' :
                                        extraction.status === 'pending' ? '处理中' : '失败'
                                      }
                                    </span>
                                    {extraction.confidence && (
                                      <span className="text-xs text-gray-500">
                                        置信度: {(extraction.confidence * 100).toFixed(1)}%
                                      </span>
                                    )}
                                  </div>
                                  <div className="text-sm text-gray-700 line-clamp-3">
                                    {extraction.extractedText || '正在处理中...'}
                                  </div>
                                  {extraction.extractedText && (
                                    <button
                                      onClick={() => navigator.clipboard.writeText(extraction.extractedText)}
                                      className="mt-2 text-xs text-blue-600 hover:text-blue-800"
                                    >
                                      复制原文案
                                    </button>
                                  )}
                                </div>
                              ))}
                            </div>
                          ) : processingVideos.has(video.id) ? (
                            <div className="flex items-center space-x-2">
                              <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-blue-600"></div>
                              <span className="text-sm text-blue-600">正在提取文案...</span>
                            </div>
                          ) : (
                            <span className="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800">
                              未提取
                            </span>
                          )}

                          {/* 改写后的文案 */}
                          {video.rewrittenTexts && video.rewrittenTexts.length > 0 && (
                            <div className="space-y-2">
                              <div className="text-xs font-medium text-orange-600 mb-1">✨ 改写文案</div>
                              {video.rewrittenTexts.map((rewrite, index) => (
                                <div key={index} className="border border-orange-200 rounded-lg p-3 bg-orange-50">
                                  <div className="flex items-center justify-between mb-2">
                                    <div className="flex items-center space-x-2">
                                      <span className="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-orange-100 text-orange-800">
                                        {rewrite.style} · {rewrite.tone}
                                      </span>
                                      <span className="text-xs text-gray-500">
                                        {new Date(rewrite.createdAt).toLocaleDateString()}
                                      </span>
                                    </div>
                                  </div>
                                  <div className="text-sm text-gray-700 line-clamp-3 mb-2">
                                    {rewrite.rewrittenText}
                                  </div>
                                  {rewrite.requirements && (
                                    <div className="text-xs text-gray-500 mb-2">
                                      要求: {rewrite.requirements}
                                    </div>
                                  )}
                                  <button
                                    onClick={() => navigator.clipboard.writeText(rewrite.rewrittenText)}
                                    className="text-xs text-orange-600 hover:text-orange-800"
                                  >
                                    复制改写文案
                                  </button>
                                </div>
                              ))}
                            </div>
                          )}
                        </div>
                      </td>
                      <td className="px-4 py-4 whitespace-nowrap text-sm text-gray-500">
                        {new Date(video.createdAt).toLocaleDateString()}
                      </td>
                      <td className="px-4 py-4 whitespace-nowrap text-right text-sm font-medium sticky-actions">
                        <div className="flex flex-col space-y-1 min-w-[100px]">
                          <button
                            onClick={() => handleViewVideo(video)}
                            className="text-indigo-600 hover:text-indigo-900 text-xs px-2 py-1 border border-indigo-200 rounded hover:bg-indigo-50"
                          >
                            查看详情
                          </button>
                          {(!video.downloadStatus || video.downloadStatus === 'pending' || video.downloadStatus === 'failed') && (
                            <button
                              onClick={() => handleDownloadFiles(video.id)}
                              disabled={processingVideos.has(video.id)}
                              className={`text-xs px-2 py-1 border rounded ${
                                processingVideos.has(video.id)
                                  ? 'text-gray-400 border-gray-200 bg-gray-50 cursor-not-allowed'
                                  : 'text-blue-600 hover:text-blue-900 border-blue-200 hover:bg-blue-50'
                              }`}
                            >
                              {processingVideos.has(video.id) ? "下载中..." : "下载文件"}
                            </button>
                          )}
                          {video.audioUrl && (
                            <button
                              onClick={() => handleTranscribeAudio(video.id)}
                              disabled={processingVideos.has(video.id)}
                              className={`text-xs px-2 py-1 border rounded ${
                                processingVideos.has(video.id)
                                  ? 'text-gray-400 border-gray-200 bg-gray-50 cursor-not-allowed'
                                  : 'text-purple-600 hover:text-purple-900 border-purple-200 hover:bg-purple-50'
                              }`}
                            >
                              {processingVideos.has(video.id) ? "识别中..." : "语音识别"}
                            </button>
                          )}
                          <button
                            onClick={() => handleExtractText(video.id)}
                            disabled={processingVideos.has(video.id)}
                            className={`text-xs px-2 py-1 border rounded ${
                              processingVideos.has(video.id)
                                ? 'text-gray-400 border-gray-200 bg-gray-50 cursor-not-allowed'
                                : 'text-green-600 hover:text-green-900 border-green-200 hover:bg-green-50'
                            }`}
                          >
                            {processingVideos.has(video.id)
                              ? "处理中..."
                              : video.audioUrl ? "提取文案" : "OCR提取"
                            }
                          </button>
                          <button
                            onClick={() => handleDeleteVideo(video.id)}
                            className="text-red-600 hover:text-red-900 text-xs px-2 py-1 border border-red-200 rounded hover:bg-red-50"
                          >
                            删除
                          </button>
                        </div>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
              {videos.length === 0 && (
                <div className="text-center py-12">
                  <p className="text-gray-500">暂无视频数据</p>
                </div>
              )}
            </div>
          </div>
        </div>
      </div>

      {/* 分页 */}
      <Pagination
        currentPage={pagination.page}
        totalPages={pagination.pages}
        totalItems={pagination.total}
        pageSize={pagination.limit}
        onPageChange={(page) => setPagination(prev => ({ ...prev, page }))}
        hasNext={pagination.page < pagination.pages}
        hasPrev={pagination.page > 1}
      />

      {/* 视频详情模态框 */}
      <VideoDetailModal
        video={selectedVideo}
        isOpen={isDetailModalOpen}
        onClose={handleCloseDetailModal}
        onDownload={handleDownloadFiles}
      />

      {/* 文案改写模态框 */}
      <TextRewriteModal
        isOpen={isRewriteModalOpen}
        onClose={() => setIsRewriteModalOpen(false)}
        onRewrite={handleBatchRewrite}
        selectedCount={selectedVideos.length}
      />

      {/* Toast通知 */}
      {toast && (
        <Toast
          message={toast.message}
          type={toast.type}
          onClose={() => setToast(null)}
        />
      )}
    </div>
  )
}
